package com.github.soiff.shadow.plugin.utils;

import com.google.common.base.MoreObjects;
import com.google.common.collect.Maps;

import java.util.Locale;
import java.util.Map;

/**
 * Created by Soiff on 2016/05/20.
 *
 * @author : Soiff
 */
public enum ThreadVars {
    APP,
    DOMAIN,
    PORT,
    LOCALE,
    SEO;

    private static ThreadLocal<Map<ThreadVars, Object>> currentEnv;

    private ThreadVars() {
    }

    private static <T> T get(ThreadVars var) {
        return (T) ((Map)currentEnv.get()).get(var);
    }

    private static void set(ThreadVars var, Object value) {
        ((Map)currentEnv.get()).put(var, value);
    }

    private static void clear(ThreadVars var) {
        ((Map)currentEnv.get()).remove(var);
    }

    public static void clearAll() {
        ((Map)currentEnv.get()).clear();
    }

    public static void setApp(Object app) {
        set(APP, app);
    }

    public static Object getApp() {
        return get(APP);
    }

    public static void clearApp() {
        clear(APP);
    }

    public static String getAppKey() {
        return "TODO: Return Proper Key";
    }

    public static void setDomain(String domain) {
        set(DOMAIN, domain);
    }

    public static String getDomain() {
        return (String) MoreObjects.firstNonNull(get(DOMAIN), "TODO: Return Proper Domain");
    }

    public static void clearDomain() {
        clear(DOMAIN);
    }

    public static void setPort(Integer port) {
        set(PORT, port);
    }

    public static void clearPort() {
        clear(PORT);
    }

    public static String getHost() {
        Integer port = (Integer)MoreObjects.firstNonNull(get(PORT), Integer.valueOf(80));
        return port.intValue() == 80?getDomain():getDomain() + ":" + port;
    }

    public static void setLocale(Locale locale) {
        set(LOCALE, locale);
    }

    public static Locale getLocale() {
        return (Locale)MoreObjects.firstNonNull(get(LOCALE), Locale.getDefault());
    }

    public static void clearLocale() {
        clear(LOCALE);
    }

    static {
        currentEnv = new ThreadLocal() {
            protected Map<ThreadVars, Object> initialValue() {
                return Maps.newHashMap();
            }
        };
    }
}
